<template>
    <view class="falce-canvas">
        <u-image
            :src="faceFile"
            :style="faceBoxStyle"
            v-show="faceFile"
            class="canvas-file"
        ></u-image>
        <u-image
            class="canvas-bg"
            width="100%"
            height="100%"
            src="@/static/images/face.png"
        ></u-image>
    </view>
</template>
<script>
export default {
    data() {
        return {
            exact: 'user', // environment 后摄像头  user 前摄像头
            steps: 0,
            width: 300,
            height: 300,
            track: null,
            faceFile: null,
            video: null,
            canvas: null,
        }
    },
    computed: {
        faceBoxStyle() {
            let style = {
                width: this.addUnit(this.width),
                height: this.addUnit(this.height),
            }
            return style
        },
    },
    mounted() {
        this.onCamera()
    },
    methods: {
        // 调取摄像头
        onCamera() {
            this.$nextTick(() => {
                let width = this.width
                let height = this.height

                this.video = document.createElement('video')
                this.video.width = width
                this.video.height = height
                this.video.style =
                    'position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);'

                this.canvas = document.createElement('canvas')
                this.canvas.width = width
                this.canvas.height = height
                this.canvas.style = 'display:none;'

                const faceBox = document.querySelector('.falce-canvas')
                faceBox.append(this.video)
                faceBox.append(this.canvas)

                const videoParam = {
                    audio: false,
                    video: {
                        facingMode: { exact: this.exact },
                        width: this.width,
                        height: this.height,
                    },
                }
                if (navigator.mediaDevices === undefined) {
                    navigator.mediaDevices = {}
                }
                if (navigator.mediaDevices.getUserMedia === undefined) {
                    this.isUse = false
                }
                if (
                    navigator.mediaDevices.getUserMedia ||
                    navigator.getUserMedia ||
                    navigator.webkitGetUserMedia ||
                    navigator.mozGetUserMedia
                ) {
                    // 调用用户媒体设备, 访问摄像头
                    this.getUserMedia(
                        videoParam,
                        (res) => {
                            this.photographSuccess(res)
                        },
                        (err) => {
                            this.photographError(err)
                        }
                    )
                }
            })
        },
        // 摄像头成功的回调
        photographSuccess(stream) {
            this.steps = 1
            this.$emit('success')
            // 将视频流设置为video元素的源
            this.video.srcObject = stream
            this.video.setAttribute('playsinline', true)
            this.video.setAttribute('webkit-playsinline', true)
            this.video.play()
            this.track = stream.getVideoTracks()[0]
        },
        // 摄像头失败的回调
        photographError(error) {
            this.$emit('error')
            this.steps = 2
            console.log(`访问用户媒体设备失败${error.name}, ${error.message}`)
        },
        // 访问用户媒体设备的兼容方法
        getUserMedia(constraints, success, error) {
            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                // 最新的标准API
                navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error)
            } else if (navigator.webkitGetUserMedia) {
                // webkit核心浏览器
                navigator.webkitGetUserMedia(constraints, success, error)
            } else if (navigator.mozGetUserMedia) {
                // firfox浏览器
                navigator.mozGetUserMedia(constraints, success, error)
            } else if (navigator.getUserMedia) {
                // 旧版API
                navigator.getUserMedia(constraints, success, error)
            }
        },
        // 拍照
        takePhoto() {
            const context = this.canvas.getContext('2d')
            context.drawImage(this.video, 0, 0, this.width, this.height)
            let img = this.canvas.toDataURL('image/png')
            this.faceFile = img
            this.video.style =
                'position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);display:none;'
            return new Promise((resolve) => {
                if (img) {
                    resolve(img)
                }
            })
        },
        // 重拍
        resetPhoto() {
            this.closeCamera()
        },
        //清空画布
        closeCamera() {
            this.faceFile = null
            this.video.style =
                'position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);display:block;'
            let cxt = this.canvas.getContext('2d')
            cxt.clearRect(0, 0, this.width, this.height)
        },
        addUnit(value = 0, unit = 'px') {
            return this.$u.test.number(value) ? `${value}${unit}` : value
        },
    },
    destroyed() {
        this.closeCamera()
        this.track.stop()
    },
}
</script>
<style lang="scss" scoped>
.falce-canvas {
    position: relative;
    width: 610rpx;
    height: 610rpx;
    overflow: hidden;
    .canvas-bg {
        position: absolute;
        left: 0;
        top: 0;
        z-index: 99;
    }
    .canvas-file {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
}
</style>
